package channelInfo

import (
	"fabric-go-sdk/sdk/sdkInfo/chaincodeInfo"
	"fabric-go-sdk/sdk/sdkInfo/orgInfo"
	"fmt"
	"github.com/hyperledger/fabric-sdk-go/pkg/client/event"
)

// todo -1.修改结构体内容 2.考虑orderer放在channel还是fabricnet中  3.并完善方法：获取orderer资源管理客户端
// ChannelInfo 通道信息
type ChannelInfo struct {
	// 通道信息
	ChannelID         string // like "mychannel"
	ChannelConfigPath string //like "fixtures/channel-artifacts/channel.tx"  用于创建通道的配置文件
	// 组织信息
	Orgs map[string]*orgInfo.OrgInfo // key-orgname value-orgInfo实例
	// 排序服务节点信息--放到Application中
	// 链码
	Chaincode map[string]*chaincodeInfo.ChaincodeInfo // key-chaincodeName value-chaincodeInfo实例
	// 监听事件
	EvClient *event.Client
	// 默认参数--用于未指定组织和用户时使用
	DefaultOrg   string
	DefaultUser  string
	DefaultAdmin string
}

// New
func New(channelId string, channelConfigPath string) *ChannelInfo {
	channel := &ChannelInfo{
		ChannelID:         channelId,
		ChannelConfigPath: channelConfigPath,
		Orgs:              map[string]*orgInfo.OrgInfo{},
		EvClient:          nil,
		Chaincode:         map[string]*chaincodeInfo.ChaincodeInfo{},
	}
	return channel
}

// GetAllMSPIDs 获取该通道的所有MSPid
func (c *ChannelInfo) GetAllMSPIDs() (mspIDs []string) {
	for _, org := range c.Orgs {
		mspIDs = append(mspIDs, org.OrgMspId)
	}
	return mspIDs
}

func (c *ChannelInfo) AddOrg(orgName string, orgInfo *orgInfo.OrgInfo) error {
	if _, ok := c.Orgs[orgName]; ok {
		return fmt.Errorf("AddOrg err:组织%v已加入通道%v，勿重复加入.", orgName, c.ChannelID)
	}
	c.Orgs[orgName] = orgInfo
	return nil
}

func (c *ChannelInfo) AddChainCode(chaincodeName string, chaincodeInfo *chaincodeInfo.ChaincodeInfo) error {
	if _, ok := c.Chaincode[chaincodeName]; ok {
		return fmt.Errorf("AddChainCode err:链码%v已存在与通道%v中.", chaincodeName, c.ChannelID)
	}
	c.Chaincode[chaincodeName] = chaincodeInfo
	return nil
}

// SetDefaultParams 设置通道中的默认参数
func (c *ChannelInfo) SetDefaultParams() error {
	if c.Orgs == nil {
		return fmt.Errorf("SetDefaultParams err: 该通道中没有组织信息，设置默认信息失败。")
	}
	for _, org := range c.Orgs {
		c.DefaultOrg = org.OrgName
		c.DefaultUser = org.NormalUsers[0]
		c.DefaultAdmin = org.AdminUser
	}
	return nil
}

//func DiscoverLocalPeers(ctxProvider contextAPI.ClientProvider, expectedPeers int) ([]fabAPI.Peer, error) {
//	ctx, err := contextImpl.NewLocal(ctxProvider)
//	if err != nil {
//		return nil, fmt.Errorf("error creating local context: %v", err)
//	}
//
//	discoveredPeers, err := retry.NewInvoker(retry.New(retry.TestRetryOpts)).Invoke(
//		func() (interface{}, error) {
//			peers, serviceErr := ctx.LocalDiscoveryService().GetPeers()
//			if serviceErr != nil {
//				return nil, fmt.Errorf("getting peers for MSP [%s] error: %v", ctx.Identifier().MSPID, serviceErr)
//			}
//			if len(peers) < expectedPeers {
//				return nil, status.New(status.TestStatus, status.GenericTransient.ToInt32(), fmt.Sprintf("Expecting %d peers but got %d", expectedPeers, len(peers)), nil)
//			}
//			return peers, nil
//		},
//	)
//	if err != nil {
//		return nil, err
//	}
//
//	return discoveredPeers.([]fabAPI.Peer), nil
//}

// todo -增加 创建EvClient方法
